#ifndef ENGINE_H
#define ENGINE_H

#include <string>
#include <set>
#include <global.h>
namespace NITK {
class Packet
{
public:
    Packet();
    ~Packet();

    bool decode(double &dbl) const;
    bool decode(int &dbl) const;
    bool decode(std::string &string) const;
    bool decode(char *buffer, int length) const;

    void encode(double val);
    void encode(int val);
    void encode(const std::string &val);
    void encode(const char *c, int size);

    int size() const;
    const char *data() const;
private:
    Packet(const char *buf, int size);
    friend class ApplicationEngine;
    struct Data {
        char *buffer;
        int size, bufferSize;
        mutable int offset;
        bool ownData;
    } d;
};

class RenderObject;
class ApplicationEngine
{
public:
    virtual ~ApplicationEngine();
    enum Type { Type_None };
    int type() const;
    const std::string &name() const;
    // ### extra info, rules and stuff

    virtual bool handlePress(const Point &pos);
    virtual bool handleDrag(const Point &pos);
    virtual bool handleRelease(const Point &pos);
    virtual void handleWindowResize(const Rectangle &rectangle);
    const std::set<RenderObject*> &renderObjects() const;
    virtual std::set<RenderObject*> renderObjectsIn(const Rectangle &rectangle) const;
    virtual RenderObject *renderObjectAt(const Point &pos) const;
    virtual void timerEvent(int id);
    int startTimer(int interval);
    bool stopTimer(int id);

    virtual void packetAvailable(const Packet *);
    int dataAvailable() const;
protected:
    ApplicationEngine(const std::string &name, int type);
private:
    struct Data {
        Data(const std::string &n, int typ) : name(n), type(typ) {}
        const std::string name;
        const int type;
        std::set<RenderObject*> renderObjects;
    } data;
    friend class RenderObject;
};
};

#endif
